package cn.emailChat.ai.replychain.util;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpHeaders;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.*;

/**
 * @Description 工具类：把邮件内容发给 DeepSeek Chat Completions，返回回答文本。
 * @Author susu
 * @Date 2025/8/18
 */
@Slf4j
@Component
public class DeepSeekMailHandler {
    /** DeepSeek API 根地址：如 <a href="https://api.deepseek.com">...</a> */
    @Value("${deepseek.api-base:https://api.deepseek.com}")
    private String apiBase;

    /** Chat Completions 路径：通常为 /chat/completions */
    @Value("${deepseek.chat-path:/chat/completions}")
    private String chatPath;

    /** API Key（Bearer） */
    @Value("${deepseek.api-key:}")
    private String apiKey;

    /** 模型名：如 deepseek-chat、deepseek-coder 等 */
    @Value("${deepseek.model:deepseek-chat}")
    private String model;

    /** 超时（毫秒） */
    @Value("${deepseek.timeout-ms:15000}")
    private int timeoutMs;

    /** 是否开启响应日志（仅用于排查问题，生产建议关闭） */
    @Value("${deepseek.debug:false}")
    private boolean debug;

    private final ObjectMapper mapper = new ObjectMapper();

    /**
     * 直接问答：传入一段 prompt，返回 DeepSeek 的回答（纯文本）
     */
    public String ask(String prompt) throws Exception {
        if (isBlank(apiKey)) {
            throw new IllegalStateException("deepseek.api-key 未配置");
        }
        List<Map<String, String>> messages = new ArrayList<>();
        messages.add(msg("system", "你是一个乐于助人的邮件助理，请用简洁、礼貌的中文回复用户问题。"));
        messages.add(msg("user", prompt));

        return callChat(messages);
    }

    /**
     * 针对邮件内容的问答：传入邮件要素，自动组织更合适的提示词
     */
    public String answerEmail(String subject, String fromEmail, String plainTextBody) {
        if (isBlank(apiKey)) {
            throw new IllegalStateException("deepseek.api-key 未配置");
        }
        String safeSubject = nvl(subject);
        String safeFrom = nvl(fromEmail);
        String safeBody = nvl(plainTextBody);

        List<Map<String, String>> messages = new ArrayList<>();
        messages.add(msg("system",
                "你是邮件自动回复助手。目标：阅读用户来信内容，给出简洁、专业、友好的中文回复。" +
                        "如果来信是问候或确认，给出礼貌确认；如果是问题，回答关键点；如有需要信息，礼貌询问。"));
        messages.add(msg("user",
                "发件人: " + safeFrom + "\n" +
                        "主题: " + safeSubject + "\n" +
                        "正文: \n" + safeBody + "\n\n" +
                        "请生成一段合适的中文回复，用第一人称，避免过度承诺；如信息不足可提出需要的具体信息。"));

        return callChat(messages);
    }

    // ================== 内部实现 ==================

    private String callChat(List<Map<String, String>> messages) {
        final String url = normalizeUrl(apiBase, chatPath);

        // 1) 构造请求 JSON
        final Map<String, Object> req = new LinkedHashMap<>();
        req.put("model", model);
        req.put("messages", messages);

        final String body;
        try {
            body = mapper.writeValueAsString(req);
        } catch (Exception e) {
            log.error("[DeepSeekClient] 序列化请求失败", e);
            return null;
        }

        // 2) 超时配置
        final RequestConfig cfg = RequestConfig.custom()
                .setConnectTimeout(timeoutMs)
                .setConnectionRequestTimeout(timeoutMs)
                .setSocketTimeout(timeoutMs)
                .build();

        // 3) 执行 HTTP 调用（外层 try 保护 HttpClient 构建/关闭，内层 try 保护 execute/读取）
        try (CloseableHttpClient http = HttpClients.custom().setDefaultRequestConfig(cfg).build()) {

            HttpPost post = new HttpPost(url);
            post.setHeader(HttpHeaders.AUTHORIZATION, "Bearer " + apiKey.trim());
            post.setHeader(HttpHeaders.CONTENT_TYPE, "application/json; charset=utf-8");
            post.setEntity(new StringEntity(body, ContentType.APPLICATION_JSON.withCharset(StandardCharsets.UTF_8)));

            try (CloseableHttpResponse resp = http.execute(post)) {
                int code = resp.getStatusLine().getStatusCode();
                InputStream is = (resp.getEntity() != null) ? resp.getEntity().getContent() : null;

                if (is == null) {
                    log.error("[DeepSeekClient] 响应实体为空，HTTP {}", code);
                    return null;
                }

                JsonNode root;
                try {
                    root = mapper.readTree(is);
                } catch (Exception e) {
                    log.error("[DeepSeekClient] 解析响应 JSON 失败，HTTP {}", code, e);
                    return null;
                }

                if (debug) {
                    log.info("[DeepSeekClient] HTTP {}: {}", code, root.toString());
                }

                if (code >= 200 && code < 300) {
                    JsonNode choices = root.get("choices");
                    if (choices != null && choices.isArray() && !choices.isEmpty()) {
                        JsonNode msg = choices.get(0).get("message");
                        if (msg != null && msg.get("content") != null) {
                            return msg.get("content").asText("");
                        }
                    }
                    log.error("[DeepSeekClient] 响应缺少 choices[0].message.content, root={}", root.toString());
                    return null;
                } else {
                    JsonNode err = root.get("error");
                    String detail = (err != null) ? err.toString() : root.toString();
                    log.error("[DeepSeekClient] 调用失败，HTTP {}，详情：{}", code, detail);
                    return null;
                }
            } catch (IOException e) {
                log.error("[DeepSeekClient] 执行 HTTP 请求失败（可能是超时/连接失败）", e);
                return null;
            }

        } catch (Exception e) {
            log.error("[DeepSeekClient] 构建或关闭 HttpClient 发生异常", e);
            return null;
        }
    }

    private Map<String, String> msg(String role, String content) {
        Map<String, String> m = new LinkedHashMap<>();
        m.put("role", role);
        m.put("content", content);
        return m;
    }

    private String normalizeUrl(String base, String path) {
        String b = base.endsWith("/") ? base.substring(0, base.length() - 1) : base;
        String p = path.startsWith("/") ? path : ("/" + path);
        return b + p;
    }

    private boolean isBlank(String s) {
        return s == null || s.trim().isEmpty();
    }

    private String nvl(String s) {
        return s == null ? "" : s;
    }
}

